package com.zboot.system.sharding.algorithm;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * testLog表的分片规则
 */
@Slf4j
public class TestLogMonthAlgorithm implements StandardShardingAlgorithm<String> {

    /**
     * 精确命中
     * @param collection 当前的库列表
     * @param preciseShardingValue 字段值
     * @return
     */
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        String logicTableName = preciseShardingValue.getLogicTableName();//取到逻辑表名
        //根据逻辑表名+分片字段，得到真实表名，比如月份为 2022-10 则真实表名为 test_log_202210
        String tableName = logicTableName  + "_"
                + preciseShardingValue.getValue().replace("-", "");//取到真实名
        log.debug("===================命中表（精确）==============");
        log.debug(tableName);
        log.debug("=============================================");
        return tableName;
    }

    /**
     * 范围命中
     * @param collection 当前的库列表
     * @param rangeShardingValue 范围值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
        String strStart = rangeShardingValue.getValueRange().lowerEndpoint();//范围的开始
        String strEnd = rangeShardingValue.getValueRange().upperEndpoint();//范围的结束
        Date dateStart = DateUtil.parse(strStart, "yyyy-MM");
        Date dateEnd = DateUtil.parse(strEnd, "yyyy-MM");

        Date dateCurrent = dateStart;
        String strCurrent = null;
        String logicTableName = rangeShardingValue.getLogicTableName();

        Set<String> tableNames = new HashSet<>();
        while(dateCurrent.before(dateEnd)) {
            //得到真实的表名，添加到set
            strCurrent = DateUtil.format(dateCurrent, "yyyyMM");
            tableNames.add(logicTableName + "_" + strCurrent);
            dateCurrent = DateUtil.offsetMonth(dateCurrent, 1);//向后移动一个月
        }
        log.debug("===================命中表（范围）==============");
        tableNames.forEach(e -> log.debug(e));
        log.debug("=============================================");
        return tableNames;
    }

    @Override
    public void init() {

    }

    @Override
    public String getType() {
        return null;
    }
}
